package oralExamSchedulingSystemTest;

import entity.Class;
import entity.Group;
import entity.Room;
import entity.Student;
import entity.TimeSlot;
import graph.Graph;
import graph.Vertex;

import java.util.ArrayList;
import java.util.LinkedList;

import junit.framework.Assert;
import junit.framework.TestCase;
import oralExamSchedulingSystem.Scheduler;
import oralExamSchedulingSystem.StudentRecord;
import oralExamSchedulingSystem.SubjectTimeTable;

import org.junit.Before;
import org.junit.Test;

public class TestScheduler extends TestCase {
	private StudentRecord studentRecord;
	private SubjectTimeTable subjectTimeTable;
	private Graph studentRecordGraph = new Graph();
	
	private String subjectName;
	private String reportingRoom;
	private ArrayList<String> roomsUsedByThisSubject;
	private String date;
	private String startTime;

	private int durationPerGroup;
	private int numberOfStudentPerGroup;

	/** The Graph g */
	private Graph studentRecordTestGraph = new Graph();
	private Graph subjectTimeTableTestGraph = new Graph();

	private Vertex vertexC1 = new Vertex(Class.class, new Class("5A"));
	private Vertex vertexC2 = new Vertex(Class.class, new Class("5B"));
	private Vertex vertexC3 = new Vertex(Class.class, new Class("5C"));
	private Vertex vertexC4 = new Vertex(Class.class, new Class("5D"));
	private Vertex vertexC5 = new Vertex(Class.class, new Class("5E"));
	

	private Vertex vertexS1 = new Vertex(Student.class, new Student(1, 1, "Ivana", 'F'));
	private Vertex vertexS2 = new Vertex(Student.class, new Student(2, 1, "Steve", 'F'));
	private Vertex vertexS3 = new Vertex(Student.class, new Student(3, 2, "Steven", 'M'));
	private Vertex vertexS4 = new Vertex(Student.class, new Student(4, 3, "Ivana", 'F'));
	private Vertex vertexS5 = new Vertex(Student.class, new Student(5, 1, "Eddie", 'F'));
	private Vertex vertexS6 = new Vertex(Student.class, new Student(6, 2, "Chris1", 'M'));
	private Vertex vertexS7 = new Vertex(Student.class, new Student(7, 3, "Chris2", 'M'));
	private Vertex vertexS8 = new Vertex(Student.class, new Student(8, 4, "Chris3", 'M'));
	private Vertex vertexS9 = new Vertex(Student.class, new Student(9, 1, "Eddie", 'F'));
	private Vertex vertexS10 = new Vertex(Student.class, new Student(10, 2, "Chris4", 'M'));
	private Vertex vertexS11 = new Vertex(Student.class, new Student(11, 3, "Chris5", 'M'));
	private Vertex vertexS12 = new Vertex(Student.class, new Student(12, 1, "Chris6", 'M'));

	private Vertex vertexG1 = new Vertex(Group.class, new Group(1));
	private Vertex vertexG2 = new Vertex(Group.class, new Group(2));
	private Vertex vertexG3 = new Vertex(Group.class, new Group(3));
	private Vertex vertexG4 = new Vertex(Group.class, new Group(4));

	private Vertex vertexR1 = new Vertex(Room.class, new Room("501"));
	private Vertex vertexR2 = new Vertex(Room.class, new Room("502"));
	

	Vertex vertexT1 = new Vertex(TimeSlot.class, new TimeSlot("9:00", 15));
	Vertex vertexT2 = new Vertex(TimeSlot.class, new TimeSlot("9:16", 15));
	private Scheduler scheduler;
	
	@Before
	public void setUp() throws Exception {
		studentRecordGraph.addVertex(vertexC1);
		studentRecordGraph.addVertex(vertexC2);
		studentRecordGraph.addVertex(vertexC3);
		studentRecordGraph.addVertex(vertexC4);
		studentRecordGraph.addVertex(vertexC5);
		
		studentRecordGraph.addVertex(vertexS1);
		studentRecordGraph.addVertex(vertexS2);
		studentRecordGraph.addVertex(vertexS3);
		studentRecordGraph.addVertex(vertexS4);
		studentRecordGraph.addVertex(vertexS5);
		studentRecordGraph.addVertex(vertexS6);
		studentRecordGraph.addVertex(vertexS7);
		studentRecordGraph.addVertex(vertexS8);
		studentRecordGraph.addVertex(vertexS9);
		studentRecordGraph.addVertex(vertexS10);
		studentRecordGraph.addVertex(vertexS11);
		studentRecordGraph.addVertex(vertexS12);

		studentRecordGraph.addEdge(vertexS1, vertexC1, 0);
		
		studentRecordGraph.addEdge(vertexS2, vertexC2, 0);
		studentRecordGraph.addEdge(vertexS3, vertexC3, 0);
		studentRecordGraph.addEdge(vertexS4, vertexC2, 0);
		
		studentRecordGraph.addEdge(vertexS5, vertexC3, 0);
		studentRecordGraph.addEdge(vertexS6, vertexC3, 0);
		studentRecordGraph.addEdge(vertexS7, vertexC3, 0);
		studentRecordGraph.addEdge(vertexS8, vertexC3, 0);
		
		studentRecordGraph.addEdge(vertexS9, vertexC4, 0);
		studentRecordGraph.addEdge(vertexS10, vertexC4, 0);
		studentRecordGraph.addEdge(vertexS11, vertexC4, 0);
		
		studentRecordGraph.addEdge(vertexS12, vertexC5, 0);
		
		studentRecordTestGraph = studentRecordGraph.shadowCopy();
		subjectTimeTableTestGraph = studentRecordGraph.shadowCopy();
		
		
		subjectTimeTableTestGraph.addVertex(vertexT1);
		subjectTimeTableTestGraph.addVertex(vertexT2);
		
	
		subjectTimeTableTestGraph.addVertex(vertexR1);
		subjectTimeTableTestGraph.addVertex(vertexR2);

		subjectTimeTableTestGraph.addVertex(vertexG1);
		subjectTimeTableTestGraph.addVertex(vertexG2);
		subjectTimeTableTestGraph.addVertex(vertexG3);
		subjectTimeTableTestGraph.addVertex(vertexG4);

		subjectTimeTableTestGraph.addEdge(vertexT1, vertexG1, 0);
		subjectTimeTableTestGraph.addEdge(vertexR1, vertexG1, 0);
	
		subjectTimeTableTestGraph.addEdge(vertexT1, vertexG2, 0);
		subjectTimeTableTestGraph.addEdge(vertexR2, vertexG2, 0);

		subjectTimeTableTestGraph.addEdge(vertexT2, vertexG3, 0);
		subjectTimeTableTestGraph.addEdge(vertexR1, vertexG3, 0);
		
		subjectTimeTableTestGraph.addEdge(vertexT2, vertexG4, 0);
		subjectTimeTableTestGraph.addEdge(vertexR2, vertexG4, 0);
		
		subjectTimeTableTestGraph.addEdge(vertexG1, vertexS1, 0);
		subjectTimeTableTestGraph.addEdge(vertexG1, vertexS2, 0);
		subjectTimeTableTestGraph.addEdge(vertexG1, vertexS5, 0);
		
		subjectTimeTableTestGraph.addEdge(vertexG2, vertexS3, 0);
		subjectTimeTableTestGraph.addEdge(vertexG2, vertexS6, 0);
		subjectTimeTableTestGraph.addEdge(vertexG2, vertexS9, 0);
		
		subjectTimeTableTestGraph.addEdge(vertexG3, vertexS7, 0);
		subjectTimeTableTestGraph.addEdge(vertexG3, vertexS10, 0);
		subjectTimeTableTestGraph.addEdge(vertexG3, vertexS12, 0);
		
		subjectTimeTableTestGraph.addEdge(vertexG3, vertexS11, 0);
		subjectTimeTableTestGraph.addEdge(vertexG3, vertexS4, 0);
		subjectTimeTableTestGraph.addEdge(vertexG3, vertexS8, 0);

		studentRecord=new StudentRecord();
		studentRecord.addStudent((Student)vertexS1.getData(), (Class)vertexC1.getData());
		
		studentRecord.addStudent((Student)vertexS2.getData(), (Class)vertexC2.getData());
		studentRecord.addStudent((Student)vertexS3.getData(), (Class)vertexC2.getData());
		studentRecord.addStudent((Student)vertexS4.getData(), (Class)vertexC2.getData());
		
		studentRecord.addStudent((Student)vertexS5.getData(), (Class)vertexC3.getData());
		studentRecord.addStudent((Student)vertexS6.getData(), (Class)vertexC3.getData());
		studentRecord.addStudent((Student)vertexS7.getData(), (Class)vertexC3.getData());
		studentRecord.addStudent((Student)vertexS8.getData(), (Class)vertexC3.getData());
		
		studentRecord.addStudent((Student)vertexS9.getData(), (Class)vertexC4.getData());
		studentRecord.addStudent((Student)vertexS10.getData(), (Class)vertexC4.getData());
		studentRecord.addStudent((Student)vertexS11.getData(), (Class)vertexC4.getData());
		
		studentRecord.addStudent((Student)vertexS12.getData(), (Class)vertexC5.getData());
		
		
		
		subjectName = "English";
		reportingRoom = "500";
		roomsUsedByThisSubject = new ArrayList<String>();
		roomsUsedByThisSubject.add("501");
		roomsUsedByThisSubject.add("502");
		date = "18-03-2013";
		startTime = "9:00";
		durationPerGroup = 15;
		numberOfStudentPerGroup = 3;
		String year="2013";
		String semester="B";
		String level="1";
		
		subjectTimeTable = new SubjectTimeTable(studentRecord.getStudentRecordGraph(), subjectName,
				reportingRoom, roomsUsedByThisSubject, date, startTime,
				durationPerGroup, numberOfStudentPerGroup,year,semester,level);
		
		scheduler = new Scheduler(subjectTimeTable,studentRecord);
	}

	
	
	public TestScheduler(String name)
	{
		super(name);
	}
	
	public void testGetContinuousIndex(){
		LinkedList<Integer> result=scheduler.getContinuousIndex(6, 8,6);
		LinkedList<Integer> expectedResult= new LinkedList<Integer>();
		expectedResult.add(0);
		expectedResult.add(1);
		expectedResult.add(2);
		expectedResult.add(3);
		expectedResult.add(4);
		expectedResult.add(5);
		expectedResult.add(0);
		expectedResult.add(1);
		Assert.assertEquals(expectedResult, result);
	}
	
	@Test
	public void testSchedule(){
		scheduler.schedule();
		System.out.println(subjectTimeTable.getGraph());
		Assert.assertEquals(true, subjectTimeTable.getGraph().toString().equals("Graph[Vertex(class entity.Student, data=Student: 1), in:[{class entity.Group,Group: 1}], out:[{class entity.Class,Class: 5A}]Vertex(class entity.Class, data=Class: 5A), in:[{class entity.Student,Student: 1}], out:[]Vertex(class entity.Student, data=Student: 2), in:[{class entity.Group,Group: 1}], out:[{class entity.Class,Class: 5B}]Vertex(class entity.Class, data=Class: 5B), in:[{class entity.Student,Student: 2},{class entity.Student,Student: 3},{class entity.Student,Student: 4}], out:[]Vertex(class entity.Student, data=Student: 3), in:[{class entity.Group,Group: 2}], out:[{class entity.Class,Class: 5B}]Vertex(class entity.Student, data=Student: 4), in:[{class entity.Group,Group: 4}], out:[{class entity.Class,Class: 5B}]Vertex(class entity.Student, data=Student: 5), in:[{class entity.Group,Group: 1}], out:[{class entity.Class,Class: 5C}]Vertex(class entity.Class, data=Class: 5C), in:[{class entity.Student,Student: 5},{class entity.Student,Student: 6},{class entity.Student,Student: 7},{class entity.Student,Student: 8}], out:[]Vertex(class entity.Student, data=Student: 6), in:[{class entity.Group,Group: 2}], out:[{class entity.Class,Class: 5C}]Vertex(class entity.Student, data=Student: 7), in:[{class entity.Group,Group: 3}], out:[{class entity.Class,Class: 5C}]Vertex(class entity.Student, data=Student: 8), in:[{class entity.Group,Group: 4}], out:[{class entity.Class,Class: 5C}]Vertex(class entity.Student, data=Student: 9), in:[{class entity.Group,Group: 2}], out:[{class entity.Class,Class: 5D}]Vertex(class entity.Class, data=Class: 5D), in:[{class entity.Student,Student: 9},{class entity.Student,Student: 10},{class entity.Student,Student: 11}], out:[]Vertex(class entity.Student, data=Student: 10), in:[{class entity.Group,Group: 3}], out:[{class entity.Class,Class: 5D}]Vertex(class entity.Student, data=Student: 11), in:[{class entity.Group,Group: 4}], out:[{class entity.Class,Class: 5D}]Vertex(class entity.Student, data=Student: 12), in:[{class entity.Group,Group: 3}], out:[{class entity.Class,Class: 5E}]Vertex(class entity.Class, data=Class: 5E), in:[{class entity.Student,Student: 12}], out:[]Vertex(class entity.TimeSlot, data=TimeSlot: 540), in:[], out:[{class entity.Group,Group: 1},{class entity.Group,Group: 2}]Vertex(class entity.TimeSlot, data=TimeSlot: 555), in:[], out:[{class entity.Group,Group: 3},{class entity.Group,Group: 4}]Vertex(class entity.Room, data=Room: 501), in:[], out:[{class entity.Group,Group: 1},{class entity.Group,Group: 3}]Vertex(class entity.Room, data=Room: 502), in:[], out:[{class entity.Group,Group: 2},{class entity.Group,Group: 4}]Vertex(class entity.Group, data=Group: 1), in:[{class entity.TimeSlot,TimeSlot: 540},{class entity.Room,Room: 501}], out:[{class entity.Student,Student: 1},{class entity.Student,Student: 2},{class entity.Student,Student: 5}]Vertex(class entity.Group, data=Group: 2), in:[{class entity.TimeSlot,TimeSlot: 540},{class entity.Room,Room: 502}], out:[{class entity.Student,Student: 3},{class entity.Student,Student: 6},{class entity.Student,Student: 9}]Vertex(class entity.Group, data=Group: 3), in:[{class entity.TimeSlot,TimeSlot: 555},{class entity.Room,Room: 501}], out:[{class entity.Student,Student: 7},{class entity.Student,Student: 10},{class entity.Student,Student: 12}]Vertex(class entity.Group, data=Group: 4), in:[{class entity.TimeSlot,TimeSlot: 555},{class entity.Room,Room: 502}], out:[{class entity.Student,Student: 11},{class entity.Student,Student: 4},{class entity.Student,Student: 8}]]"));
	}
}
	
	

//	@Test
//	public void testScheduler() {
//		//fail("test");
//		int roomNum = 101;
//		
//		
//		Date date = null;
//		java.text.SimpleDateFormat simple = new java.text.SimpleDateFormat();
//		try{
//			simple.applyPattern("HHmmss");
//			date = simple.parse("131313");
//			//scheduler.schedule(timetable, student)
//		}
//		catch(Exception e){
//			
//		}
//		finally {
//			
//		}
//		
//		Scheduler s1 = new Scheduler();
//		Timetable t1 = new Timetable();
//		
//		
//		//s1.schedule(t1, student);
//		
//		assertEquals(date, t1.getDate());
//		//result = scheduler.schedule(timetable, student);
//		//assertEquals(, );
//	}
